package com.csw.scala

object Demo11Fun2 {
  def main(args: Array[String]): Unit = {

    /**
      * 面向对象编程，是将对象传来传去，对象是有类型的，方法的参数是有类型限制的
      *
      * 面向函数编程，是将函数传来传去，函数也是有类型的，接收函数的方法同样也是有类型的
      *
      *
      * 高阶函数
      * 1、以函数作为参数
      * 2、以函数作为返回值
      */

    /**
      *
      * 函数的类型是由函数的参数类型和函数的返回值类型决定的
      *
      * def fun(str: String): Int ={
      *     str.toInt + 1
      * }
      *
      * 这是一个参数为String，返回值为Int的函数
      */

    /**
      * 以函数作为参数去定义一个方法，方法的参数就是一个函数
      *
      * fun1的参数是一个函数，是一个参数类型为String，返回值类型为Int的函数
      *
      * String =>  Int    |||描述函数的类型
      *
      */
    def fun1(f: String => Int) = {

      //f相当于fun2的引用
      //调用传进来的函数
      val i: Int = f("100")
      println(i)
    }

    //这是一个参数为String类型 返回值为Int类型的函数
    def fun2(str: String): Int ={
      str.toInt + 1
    }

    def fun3(str: String) =str.toInt + 2

    //调用fun1,传入fun2和fun3
    fun1(fun2)
    fun1(fun3)

    //使用lambda表达式调用函数
    fun1((s: String) => s.toInt + 100)
    //lambda表达式的参数类型可以自动推断出来
    fun1(s => s.toInt + 1000)
    //如果lambda表达式的参数只使用了一次可以通过下划线代替
    fun1(_.toInt + 10000)


    /**
      * lambda表达式---对定义函数的简写----匿名函数
      * (s: String) => s.toInt + 1
      *
      * => 前面是函数的参数名和参数类型
      * => 后面是函数的返回值和函数体
      */
    def fun4(s: String): Int ={
      s.toInt + 1
    }

    val lam: String => Int = (s: String) => s.toInt + 1
    println(lam("100"))
  }
}
